<template>
  <view class="clock-container">
    <!-- 顶部信息 -->
    <view class="header-info">
      <view class="time-display">
        <text class="time">{{ currentTime }}</text>
        <text class="date">{{ currentDate }}</text>
      </view>
    </view>
    
    <!-- 地图区域 -->
    <view class="map-container">
      <map
        id="map"
        class="map"
        :latitude="factoryLocation.latitude"
        :longitude="factoryLocation.longitude"
        :markers="markers"
        :circles="circles"
        :scale="16"
        show-location
        enable-rotate
        enable-satellite
      ></map>
      <view class="location-info">
        <text class="location-status" :class="{ 'in-range': isInRange }">
          {{ isInRange ? '您在打卡范围内' : '您不在打卡范围内' }}
        </text>
      </view>
    </view>
    
    <!-- 打卡状态 -->
    <view class="clock-status">
      <view class="status-circle" :class="{ 'clocked-in': todayRecord?.clockInTime, 'clocked-out': todayRecord?.clockOutTime }">
        <text class="status-text">{{ getStatusText() }}</text>
      </view>
    </view>
    
    <!-- 打卡记录 -->
    <view class="record-info" v-if="todayRecord">
      <view class="record-item" v-if="todayRecord.clockInTime">
        <text class="record-label">上班打卡</text>
        <text class="record-time">{{ formatTime(todayRecord.clockInTime) }}</text>
        <text class="record-status success">成功</text>
      </view>
      <view class="record-item" v-if="todayRecord.clockOutTime">
        <text class="record-label">下班打卡</text>
        <text class="record-time">{{ formatTime(todayRecord.clockOutTime) }}</text>
        <text class="record-status success">成功</text>
      </view>
    </view>
    
    <!-- 打卡按钮 -->
    <view class="clock-actions">
      <button 
        class="clock-btn clock-in" 
        :disabled="todayRecord?.clockInTime || !isInRange" 
        @tap="handleClockIn"
        :loading="loading === 'in'"
      >
        {{ todayRecord?.clockInTime ? '已打卡' : '上班打卡' }}
      </button>
      
      <button 
        class="clock-btn clock-out" 
        :disabled="!todayRecord?.clockInTime || todayRecord?.clockOutTime || !isInRange" 
        @tap="handleClockOut"
        :loading="loading === 'out'"
      >
        {{ todayRecord?.clockOutTime ? '已打卡' : '下班打卡' }}
      </button>
    </view>
    
    <!-- 提示信息 -->
    <view class="tips">
      <text class="tip-text">提示：请在工厂范围内(蓝色圆圈)进行打卡</text>
      <text class="tip-text">打卡异常请联系管理员</text>
    </view>
  </view>
</template>

<script setup>
import { ref, onMounted, computed } from 'vue'
import { onShow, onUnload } from '@dcloudio/uni-app'
import dayjs from 'dayjs'
import attendance from '@/api/attendance'

// 状态
const currentTime = ref('')
const currentDate = ref('')
const todayRecord = ref(null)
const loading = ref('')  // 'in' 或 'out' 或 ''
const isInRange = ref(false)

// 工厂位置信息（这里设置为固定值，实际应该从后端获取）
const factoryLocation = ref({
  latitude: 33.060433, 
  longitude: 112.946829,
  radius: 500 // 打卡范围半径（米）
})

// 用户位置信息
const userLocation = ref({
  latitude: 0,
  longitude: 0,
  accuracy: 0
})

// 地图标记点
const markers = ref([
  {
    id: 1,
    latitude: factoryLocation.value.latitude,
    longitude: factoryLocation.value.longitude,
    iconPath: '/static/images/factory.png', // 需要添加一个工厂图标
    width: 30,
    height: 30,
    callout: {
      content: '工厂位置',
      color: '#000000',
      fontSize: 12,
      borderRadius: 3,
      bgColor: '#ffffff',
      padding: 5,
      display: 'ALWAYS'
    }
  }
])

// 地图圆圈（打卡范围）
const circles = ref([
  {
    latitude: factoryLocation.value.latitude,
    longitude: factoryLocation.value.longitude,
    color: '#1890FF20', // 蓝色半透明
    fillColor: '#1890FF10', // 淡蓝色填充
    radius: factoryLocation.value.radius,
    strokeWidth: 2
  }
])

// 更新时间
function updateTime() {
  const now = dayjs()
  currentTime.value = now.format('HH:mm:ss')
  currentDate.value = now.format('YYYY年MM月DD日 dddd')
}

// 格式化时间
function formatTime(time) {
  return dayjs(time).format('HH:mm:ss')
}

// 获取状态文本
function getStatusText() {
  if (!todayRecord.value) {
    return '未打卡'
  }
  
  if (todayRecord.value.clockInTime && todayRecord.value.clockOutTime) {
    return '已完成'
  }
  
  if (todayRecord.value.clockInTime) {
    return '已上班'
  }
  
  return '未打卡'
}

// 计算两点之间的距离（米）- 修正版
function calculateDistance(lat1, lon1, lat2, lon2) {
  // 如果坐标相同或非常接近，直接返回0
  if (Math.abs(lat1 - lat2) < 0.0000001 && Math.abs(lon1 - lon2) < 0.0000001) {
    return 0;
  }
  
  // 使用Haversine公式计算球面距离
  const R = 6371000; // 地球半径，单位米
  const dLat = (lat2 - lat1) * Math.PI / 180;
  const dLon = (lon2 - lon1) * Math.PI / 180;
  const a = 
    Math.sin(dLat/2) * Math.sin(dLat/2) +
    Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) * 
    Math.sin(dLon/2) * Math.sin(dLon/2);
  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
  const distance = R * c;
  
  console.log('计算距离:', {
    userLat: lat1,
    userLon: lon1,
    factoryLat: lat2,
    factoryLon: lon2,
    distance: distance
  });
  
  return distance;
}

// 检查是否在打卡范围内 - 修正版
function checkInRange() {
  // 如果没有获取到用户位置，直接返回false
  if (!userLocation.value || !userLocation.value.latitude) {
    console.log('未获取到用户位置');
    isInRange.value = false;
    return false;
  }
  
  const distance = calculateDistance(
    userLocation.value.latitude,
    userLocation.value.longitude,
    factoryLocation.value.latitude,
    factoryLocation.value.longitude
  );
  
  // 考虑位置精度，如果用户位置精度值大于0，将其考虑进去
  const effectiveRadius = factoryLocation.value.radius + (userLocation.value.accuracy || 0);
  
  console.log('范围检查:', {
    distance: distance,
    radius: factoryLocation.value.radius,
    effectiveRadius: effectiveRadius,
    isInRange: distance <= effectiveRadius
  });
  
  isInRange.value = distance <= effectiveRadius;
  return isInRange.value;
}

// 获取位置信息 - 修正版
async function getLocation() {
  return new Promise((resolve, reject) => {
    // 先获取授权状态
    uni.getSetting({
      success: (res) => {
        if (res.authSetting['scope.userLocation'] !== true) {
          // 如果没有授权，先获取授权
          uni.authorize({
            scope: 'scope.userLocation',
            success: () => {
              // 授权成功后获取位置
              getLocationInfo(resolve, reject);
            },
            fail: (err) => {
              uni.showModal({
                title: '提示',
                content: '需要获取您的地理位置，请确认授权，否则无法打卡',
                showCancel: false,
                success: () => {
                  // 打开设置页面让用户手动授权
                  uni.openSetting({
                    success: (settingRes) => {
                      if (settingRes.authSetting['scope.userLocation']) {
                        getLocationInfo(resolve, reject);
                      } else {
                        reject(new Error('未获得位置权限'));
                      }
                    }
                  });
                }
              });
            }
          });
        } else {
          // 已经授权，直接获取位置
          getLocationInfo(resolve, reject);
        }
      },
      fail: (err) => {
        reject(err);
      }
    });
  });
}

// 实际获取位置的函数 - 修正版
function getLocationInfo(resolve, reject) {
  uni.getLocation({
    type: 'gcj02',
    isHighAccuracy: true, // 开启高精度定位
    highAccuracyExpireTime: 3000, // 高精度定位超时时间，单位ms
    success: (res) => {
      console.log('获取位置成功:', res);
      
      userLocation.value = {
        latitude: res.latitude,
        longitude: res.longitude,
        accuracy: res.accuracy
      };
      
      // 添加用户位置标记
      const userMarker = {
        id: 2,
        latitude: res.latitude,
        longitude: res.longitude,
        iconPath: '/static/images/user-location.png',
        width: 30,
        height: 30
      };
      
      // 更新标记点
      if (markers.value.length > 1) {
        markers.value[1] = userMarker;
      } else {
        markers.value.push(userMarker);
      }
      
      // 检查是否在范围内
      checkInRange();
      
      // 如果工厂位置未设置，使用当前位置作为工厂位置（仅用于测试）
      if (factoryLocation.value.latitude === 31.2304 && factoryLocation.value.longitude === 121.4737) {
        console.log('使用当前位置作为工厂位置');
        factoryLocation.value = {
          latitude: res.latitude,
          longitude: res.longitude,
          radius: 500
        };
        
        // 更新工厂标记
        markers.value[0] = {
          id: 1,
          latitude: res.latitude,
          longitude: res.longitude,
          iconPath: '/static/images/factory.png',
          width: 30,
          height: 30,
          callout: {
            content: '工厂位置',
            color: '#000000',
            fontSize: 12,
            borderRadius: 3,
            bgColor: '#ffffff',
            padding: 5,
            display: 'ALWAYS'
          }
        };
        
        // 更新圆圈
        circles.value[0] = {
          latitude: res.latitude,
          longitude: res.longitude,
          color: '#1890FF20',
          fillColor: '#1890FF10',
          radius: 500,
          strokeWidth: 2
        };
        
        // 重新检查范围
        checkInRange();
      }
      
      resolve(res);
    },
    fail: (err) => {
      console.error('获取位置失败:', err);
      uni.showToast({
        title: '获取位置失败，请检查权限设置',
        icon: 'none'
      });
      reject(err);
    }
  });
}

// 开始位置监听 - 修正版
function startLocationWatch() {
  uni.startLocationUpdate({
    type: 'gcj02',
    success: () => {
      console.log('开始监听位置变化');
      
      // 监听位置变化
      uni.onLocationChange((res) => {
        console.log('位置变化:', res);
        
        userLocation.value = {
          latitude: res.latitude,
          longitude: res.longitude,
          accuracy: res.accuracy
        };
        
        // 更新用户位置标记
        if (markers.value.length > 1) {
          markers.value[1].latitude = res.latitude;
          markers.value[1].longitude = res.longitude;
        } else {
          markers.value.push({
            id: 2,
            latitude: res.latitude,
            longitude: res.longitude,
            iconPath: '/static/images/user-location.png',
            width: 30,
            height: 30
          });
        }
        
        // 检查是否在范围内
        checkInRange();
      });
    },
    fail: (err) => {
      console.error('开始位置监听失败:', err);
    }
  });
}

// 停止位置监听
function stopLocationWatch() {
  uni.stopLocationUpdate({
    success: () => {
      console.log('停止监听位置变化');
      uni.offLocationChange();
    }
  });
}

// 获取今日打卡记录
async function getTodayRecord() {
  try {
    const data = await attendance.getTodayAttendance();
    todayRecord.value = data;
  } catch (error) {
    console.error('获取打卡记录失败:', error);
    uni.showToast({
      title: '获取打卡记录失败',
      icon: 'none'
    });
  }
}

// 上班打卡
async function handleClockIn() {
  if (todayRecord.value?.clockInTime || !isInRange.value) return;
  
  try {
    loading.value = 'in';
    
    // 提交打卡
    const result = await attendance.clockInWithLocation({
      latitude: userLocation.value.latitude,
      longitude: userLocation.value.longitude,
      accuracy: userLocation.value.accuracy,
      type: 'in'
    });
    
    if (result) {
      uni.showToast({
        title: '上班打卡成功',
        icon: 'success'
      });
      
      // 刷新打卡记录
      await getTodayRecord();
    }
  } catch (error) {
    console.error('上班打卡失败:', error);
    uni.showToast({
      title: error.message || '上班打卡失败',
      icon: 'none'
    });
  } finally {
    loading.value = '';
  }
}

// 下班打卡
async function handleClockOut() {
  if (!todayRecord.value?.clockInTime || todayRecord.value?.clockOutTime || !isInRange.value) return;
  
  try {
    loading.value = 'out';
    
    // 提交打卡
    const result = await attendance.clockOutWithLocation({
      latitude: userLocation.value.latitude,
      longitude: userLocation.value.longitude,
      accuracy: userLocation.value.accuracy,
      type: 'out',
      attendanceId: todayRecord.value.id
    });
    
    if (result) {
      uni.showToast({
        title: '下班打卡成功',
        icon: 'success'
      });
      
      // 刷新打卡记录
      await getTodayRecord();
    }
  } catch (error) {
    console.error('下班打卡失败:', error);
    uni.showToast({
      title: error.message || '下班打卡失败',
      icon: 'none'
    });
  } finally {
    loading.value = '';
  }
}

// 定时更新时间
let timer = null;

onMounted(() => {
  // 初始化时间
  updateTime();
  
  // 设置定时器，每秒更新时间
  timer = setInterval(updateTime, 1000);
  
  // 获取位置并开始监听
  getLocation().then(() => {
    startLocationWatch();
    
    // 测试用：3秒后再次检查范围
    setTimeout(() => {
      console.log('延时检查范围');
      checkInRange();
    }, 3000);
  });
  
  // 获取今日打卡记录
  getTodayRecord();
});

onShow(() => {
  // 页面显示时刷新打卡记录
  getTodayRecord();
});

onUnload(() => {
  // 页面卸载时清除定时器和位置监听
  if (timer) {
    clearInterval(timer);
  }
  stopLocationWatch();
});
</script>

<style lang="scss">
.clock-container {
  min-height: 100vh;
  background-color: #f5f5f5;
  padding: 20rpx;
  display: flex;
  flex-direction: column;
  
  .header-info {
    background-color: #fff;
    border-radius: 20rpx;
    padding: 20rpx;
    margin-bottom: 20rpx;
    box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.05);
    
    .time-display {
      text-align: center;
      
      .time {
        font-size: 48rpx;
        font-weight: bold;
        color: #333;
        display: block;
      }
      
      .date {
        font-size: 24rpx;
        color: #666;
      }
    }
  }
  
  .map-container {
    width: 100%;
    height: 400rpx;
    border-radius: 20rpx;
    overflow: hidden;
    margin-bottom: 20rpx;
    position: relative;
    
    .map {
      width: 100%;
      height: 100%;
    }
    
    .location-info {
      position: absolute;
      bottom: 0;
      left: 0;
      right: 0;
      background-color: rgba(255, 255, 255, 0.8);
      padding: 10rpx;
      text-align: center;
      
      .location-status {
        font-size: 28rpx;
        font-weight: bold;
        color: #ff4d4f;
        
        &.in-range {
          color: #52c41a;
        }
      }
    }
  }
  
  .clock-status {
    display: flex;
    justify-content: center;
    margin: 20rpx 0;
    
    .status-circle {
      width: 180rpx;
      height: 180rpx;
      border-radius: 50%;
      background-color: #f0f0f0;
      display: flex;
      align-items: center;
      justify-content: center;
      box-shadow: 0 6rpx 20rpx rgba(0, 0, 0, 0.1);
      
      &.clocked-in {
        background-color: #e6f7ff;
        border: 4rpx solid #1890ff;
      }
      
      &.clocked-out {
        background-color: #f6ffed;
        border: 4rpx solid #52c41a;
      }
      
      .status-text {
        font-size: 32rpx;
        font-weight: bold;
        color: #333;
      }
    }
  }
  
  .record-info {
    background-color: #fff;
    border-radius: 20rpx;
    padding: 20rpx;
    margin-bottom: 20rpx;
    
    .record-item {
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: 16rpx;
      border-bottom: 1rpx solid #f0f0f0;
      
      &:last-child {
        border-bottom: none;
      }
      
      .record-label {
        font-size: 28rpx;
        color: #333;
        font-weight: bold;
      }
      
      .record-time {
        font-size: 28rpx;
        color: #666;
      }
      
      .record-status {
        font-size: 24rpx;
        
        &.success {
          color: #52c41a;
        }
        
        &.fail {
          color: #f5222d;
        }
      }
    }
  }
  
  .clock-actions {
    display: flex;
    justify-content: space-around;
    margin: 20rpx 0;
    
    .clock-btn {
      width: 45%;
      height: 90rpx;
      border-radius: 45rpx;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 32rpx;
      font-weight: bold;
      
      &.clock-in {
        background-color: #1890ff;
        color: #fff;
        
        &:disabled {
          background-color: #bae7ff;
        }
      }
      
      &.clock-out {
        background-color: #52c41a;
        color: #fff;
        
        &:disabled {
          background-color: #d9f7be;
        }
      }
    }
  }
  
  .tips {
    margin-top: 20rpx;
    
    .tip-text {
      font-size: 24rpx;
      color: #999;
      text-align: center;
      display: block;
      line-height: 1.8;
    }
  }
}
</style> 